package com.atguigu.tingshu.album.manager;

import cn.hutool.core.io.FileUtil;
import com.atguigu.tingshu.album.config.VodConstantProperties;
import com.atguigu.tingshu.common.execption.BusinessException;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.common.utils.ThrowUtil;
import com.qcloud.vod.VodUploadClient;
import com.qcloud.vod.model.VodUploadRequest;
import com.qcloud.vod.model.VodUploadResponse;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.ims.v20201229.ImsClient;
import com.tencentcloudapi.ims.v20201229.models.ImageModerationRequest;
import com.tencentcloudapi.ims.v20201229.models.ImageModerationResponse;
import com.tencentcloudapi.tms.v20200713.TmsClient;
import com.tencentcloudapi.tms.v20200713.models.TextModerationRequest;
import com.tencentcloudapi.tms.v20200713.models.TextModerationResponse;
import com.tencentcloudapi.vod.v20180717.VodClient;
import com.tencentcloudapi.vod.v20180717.models.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.Base64;
import java.util.List;

/**
 * @author dyl
 * @className VodManager
 * @description
 * @date 2025/10/30 10:52@version 1.0
 */
@Component
@Slf4j
public class VodManager {

    @Autowired
    private VodConstantProperties vodConstantProperties;

    @Autowired
    private VodUploadClient vodClient;

    @Autowired
    private Credential cred;

    public VodUploadResponse uploadVideo(String fileName, String filePath) {
        VodUploadRequest request = new VodUploadRequest();
        String localFilePath = vodConstantProperties.getTempPath() + filePath + File.separator + fileName;
        request.setMediaFilePath(localFilePath);
        VodUploadResponse response = null;
        try {
            response = vodClient.upload(vodConstantProperties.getRegion(), request);
            log.info("Upload FileId = {}", response.getFileId());
        } catch (Exception e) {
            // 业务方进行异常处理
            log.error("Upload Err", e);
        }
        ThrowUtil.throwIf(response == null, "上传失败, request为null");
        return response;
    }

    /**
     * @param @param mediaFileIds
     * @return @return {@code DescribeMediaInfosResponse }
     * @name getFileOriginalInfo
     * @description 获取文件原始信息（时长、文件类型、大小）
     */
    public DescribeMediaInfosResponse getFileOriginalInfo(String[] mediaFileIds) {
        try {
            // 实例化要请求产品的client对象,clientProfile是可选的
            VodClient client = createClient("vod.tencentcloudapi.com", VodClient::new);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            DescribeMediaInfosRequest req = new DescribeMediaInfosRequest();
            req.setFileIds(mediaFileIds);
            // 返回的resp是一个DescribeMediaInfosResponse的实例，与请求对象对应
            // 输出json格式的字符串回包
            return client.DescribeMediaInfos(req);
        } catch (TencentCloudSDKException e) {
            log.error("获取文件原始信息失败", e);
            throw new BusinessException(ResultCodeEnum.SERVICE_ERROR, "获取文件原始信息失败");
        }
    }

    /**
     * @param
     * @return @return boolean
     * @name checkTextContent
     * @description 文本内容审核
     */
    public boolean checkTextContent(String content) {
        String base64Code = Base64.getEncoder().encodeToString(content.getBytes());
        try {
            // 实例化要请求产品的client对象,clientProfile是可选的
            TmsClient client = createClient("tms.tencentcloudapi.com", TmsClient::new);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            TextModerationRequest req = new TextModerationRequest();
            req.setContent(base64Code);
            // 返回的resp是一个TextModerationResponse的实例，与请求对象对应
            TextModerationResponse resp = client.TextModeration(req);
            return resp.getSuggestion().equals("Pass");
        } catch (TencentCloudSDKException e) {
            log.error("文本内容审核失败", e);
        }
        return false;
    }

    /**
     * @param @param file
     * @return @return boolean
     * @name checkImgContent
     * @description 图片内容审核
     */
    public boolean checkImgContent(File file) {
        String base64Code = Base64.getEncoder().encodeToString(FileUtil.readBytes(file));
        try {
            // 实例化要请求产品的client对象,clientProfile是可选的
            ImsClient client = createClient("ims.tencentcloudapi.com", (cred, region, profile) -> new ImsClient(cred, "ap-guangzhou", profile));
            // 实例化一个请求对象,每个接口都会对应一个request对象
            ImageModerationRequest req = new ImageModerationRequest();
            req.setFileContent(base64Code);
            // 返回的resp是一个ImageModerationResponse的实例，与请求对象对应
            ImageModerationResponse resp = client.ImageModeration(req);
            return resp.getSuggestion().equals("Pass");
        } catch (TencentCloudSDKException e) {
            log.error("图片内容审核失败", e);
        }
        return false;
    }

    /**
     * @param @param fileId
     * @return @return {@code String }
     * @name createVideoReviewTack
     * @description 创建视频审核任务
     */
    public String createVideoReviewTack(String fileId) {
        try {
            // 实例化要请求产品的client对象,clientProfile是可选的
            VodClient client = createClient("vod.tencentcloudapi.com", VodClient::new);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            ReviewAudioVideoRequest req = new ReviewAudioVideoRequest();
            req.setFileId(fileId);
            // 返回的resp是一个ReviewAudioVideoResponse的实例，与请求对象对应
            ReviewAudioVideoResponse resp = client.ReviewAudioVideo(req);
            // 输出json格式的字符串回包
            return resp.getRequestId();
        } catch (TencentCloudSDKException e) {
            log.error("音视频内容审核失败", e);
        }
        return null;
    }

    public List<Boolean> getTaskResult(String taskId) {
        try {
            VodClient client = createClient("vod.tencentcloudapi.com", VodClient::new);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            DescribeTaskDetailRequest req = new DescribeTaskDetailRequest();
            req.setTaskId(taskId);
            // 返回的resp是一个DescribeTaskDetailResponse的实例，与请求对象对应
            DescribeTaskDetailResponse resp = client.DescribeTaskDetail(req);
            // 输出json格式的字符串回包
            String status = resp.getStatus();
            if (status.equals("FINISH")) {
                return List.of(true, resp.getReviewAudioVideoTask().getOutput().getSuggestion().equals("pass"));
            } else {
                return List.of(false, true);
            }
        } catch (TencentCloudSDKException e) {
            log.error("音视频内容审核失败", e);
        }
        return List.of(false, false);
    }

    /**
     * 创建腾讯云API客户端的通用方法
     *
     * @param endpoint      服务端点
     * @param clientFactory 客户端工厂函数
     * @param <T>           客户端类型
     * @return 客户端实例
     */
    private <T> T createClient(String endpoint, ClientFactory<T> clientFactory) {
        // 实例化一个http选项，可选的，没有特殊需求可以跳过
        HttpProfile httpProfile = new HttpProfile();
        httpProfile.setEndpoint(endpoint);
        // 实例化一个client选项，可选的，没有特殊需求可以跳过
        ClientProfile clientProfile = new ClientProfile();
        clientProfile.setHttpProfile(httpProfile);
        // 创建凭证
        Credential credential = new Credential(vodConstantProperties.getSecretId(), vodConstantProperties.getSecretKey());
        // 实例化要请求产品的client对象,clientProfile是可选的
        return clientFactory.create(credential, vodConstantProperties.getRegion(), clientProfile);
    }

    /**
     * 客户端工厂函数式接口
     *
     * @param <T> 客户端类型
     */
    @FunctionalInterface
    private interface ClientFactory<T> {
        T create(Credential cred, String region, ClientProfile profile);
    }
}
